﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Windows.Input;
using ContactTracing.Core;

namespace ContactTracing.ViewModel
{
    public class ContactViewModel : ObservableObject
    {
        #region Members
        public Contact Contact;
        private string _relationshipToLastSourceCase = String.Empty;
        private string _lastSourceCaseContactTypes = String.Empty;
        #endregion // Members

        #region Static Members
        public static string Male = String.Empty;
        public static string Female = String.Empty;
        #endregion // Static Members

        #region Properties
        public bool IsLocked
        {
            get
            {
                return Contact.IsLocked;
            }
            set
            {
                if (Contact.IsLocked != value)
                {
                    Contact.IsLocked = value;
                    RaisePropertyChanged("IsLocked");
                }
            }
        }
        public FollowUpWindowViewModel FollowUpWindowViewModel
        {
            get
            {
                return Contact.FollowUpWindowViewModel;
            }
            set
            {
                if (Contact.FollowUpWindowViewModel != value)
                {
                    Contact.FollowUpWindowViewModel = value;
                    RaisePropertyChanged("FollowUpWindowViewModel");
                }
            }
        }
        public string RecordId
        {
            get { return Contact.RecordId; }
            set
            {
                if (Contact.RecordId != value)
                {
                    Contact.RecordId = value;
                    RaisePropertyChanged("RecordId");
                }
            }
        }
        public string Surname
        {
            get { return Contact.Surname; }
            set
            {
                if (Contact.Surname != value)
                {
                    Contact.Surname = value;
                    RaisePropertyChanged("Surname");
                }
            }
        }
        public string OtherNames
        {
            get { return Contact.OtherNames; }
            set
            {
                if (Contact.OtherNames != value)
                {
                    Contact.OtherNames = value;
                    RaisePropertyChanged("OtherNames");
                }
            }
        }        
        public string Gender
        {
            get { return Contact.Gender; }
            set
            {
                if (Contact.Gender != value)
                {
                    Contact.Gender = value;
                    RaisePropertyChanged("Gender");
                }
            }
        }
        public string GenderAbbreviation
        {
            get 
            {
                if (this.Gender.Equals(ContactViewModel.Female)) { return "F"; }
                else if (this.Gender.Equals(ContactViewModel.Male)) { return "M"; }
                else return String.Empty;
            }
        }
        public double? Age
        {
            get { return Contact.Age; }
            set
            {
                Contact.Age = value;
                RaisePropertyChanged("Age");
                RaisePropertyChanged("AgeYears");
            }
        }
        public double? AgeYears
        {
            get { return Contact.AgeYears; }
        }
        public AgeUnits? AgeUnit
        {
            get { return Contact.AgeUnit; }
            set
            {
                if (Contact.AgeUnit != value)
                {
                    Contact.AgeUnit = value;
                    RaisePropertyChanged("AgeUnit");
                }
            }
        }
        public DateTime? FirstSaveTime
        {
            get { return Contact.FirstSaveTime; }
            set
            {
                if (Contact.FirstSaveTime != value)
                {
                    Contact.FirstSaveTime = value;
                    RaisePropertyChanged("FirstSaveTime");
                }
            }
        }
        public DateTime? DateOfLastContact
        {
            get { return Contact.DateOfLastContact; }
            set
            {
                if (Contact.DateOfLastContact != value)
                {
                    Contact.DateOfLastContact = value;
                    RaisePropertyChanged("DateOfLastContact");
                }
            }
        }
        public CaseViewModel LastSourceCase
        {
            get
            {
                return Contact.LastSourceCase;
            }
            set
            {
                if (Contact.LastSourceCase != value)
                {
                    Contact.LastSourceCase = value;
                    RaisePropertyChanged("LastSourceCase");
                }
            }
        }

        public string RelationshipToLastSourceCase
        {
            get
            {
                return _relationshipToLastSourceCase;
            }
            set
            {
                if (_relationshipToLastSourceCase != value)
                {
                    _relationshipToLastSourceCase = value;
                    RaisePropertyChanged("RelationshipToLastSourceCase");
                }
            }
        }

        public string LastSourceCaseContactTypes
        {
            get
            {
                return _lastSourceCaseContactTypes;
            }
            set
            {
                if (_lastSourceCaseContactTypes != value)
                {
                    _lastSourceCaseContactTypes = value;
                    RaisePropertyChanged("LastSourceCaseContactTypes");
                }
            }
        }
        public DateTime? DateOfLastFollowUp
        {
            get 
            {
                if (DateOfLastContact.HasValue)
                {
                    return Contact.DateOfLastContact.Value.AddDays(Core.Common.DaysInWindow);
                }
                else
                {
                    return null;
                }
            }
        }
        public string Village
        {
            get { return Contact.Village; }
            set
            {
                if (Contact.Village != value)
                {
                    Contact.Village = value;
                    RaisePropertyChanged("Village");
                }
            }
        }
        public string SubCounty
        {
            get { return Contact.SubCounty; }
            set
            {
                if (Contact.SubCounty != value)
                {
                    Contact.SubCounty = value;
                    RaisePropertyChanged("SubCounty");
                }
            }
        }
        public string District
        {
            get { return Contact.District; }
            set
            {
                if (Contact.District != value)
                {
                    Contact.District = value;
                    RaisePropertyChanged("District");
                }
            }
        }
        public string RiskLevel
        {
            get { return Contact.RiskLevel; }
            set
            {
                if (Contact.RiskLevel != value)
                {
                    Contact.RiskLevel = value;
                    RaisePropertyChanged("RiskLevel");
                }
            }
        }
        public string HeadOfHousehold
        {
            get { return Contact.HeadOfHousehold; }
            set
            {
                if (Contact.HeadOfHousehold != value)
                {
                    Contact.HeadOfHousehold = value;
                    RaisePropertyChanged("HeadOfHousehold");
                }
            }
        }
        public string LC1Chairman
        {
            get { return Contact.LC1Chairman; }
            set
            {
                if (Contact.LC1Chairman != value)
                {
                    Contact.LC1Chairman = value;
                    RaisePropertyChanged("LC1Chairman");
                }
            }
        }
        public string Phone
        {
            get { return Contact.Phone; }
            set
            {
                if (Contact.Phone != value)
                {
                    Contact.Phone = value;
                    RaisePropertyChanged("Phone");
                }
            }
        }

        public string HCW
        {
            get { return Contact.HCW; }
            set
            {
                if (Contact.HCW != value)
                {
                    Contact.HCW = value;
                    RaisePropertyChanged("HCW");
                }
            }
        }
        public string HCWFacility
        {
            get { return Contact.HCWFacility; }
            set
            {
                if (Contact.HCWFacility != value)
                {
                    Contact.HCWFacility = value;
                    RaisePropertyChanged("HCWFacility");
                }
            }
        }
        public string FinalOutcome
        {
            get { return Contact.FinalOutcome; }
            set
            {
                if (Contact.FinalOutcome != value)
                {
                    Contact.FinalOutcome = value;
                    RaisePropertyChanged("FinalOutcome");
                }
            }
        }
        public string FinalOutcomeDisplay
        {
            get 
            {
                switch (FinalOutcome)
                {
                    case "1":
                        return "Discharged from follow-up";
                    case "2":
                        return "Developed symptoms & isolated";
                    case "3":
                        return "Dropped from follow-up";
                    default:
                        return String.Empty;
                }
            }
        }
        public bool HasFinalOutcome
        {
            get
            {
                return !(String.IsNullOrEmpty(FinalOutcome));
            }
        }
        public bool IsCase
        {
            get { return Contact.IsCase; }
            set
            {
                if (Contact.IsCase != value)
                {
                    Contact.IsCase = value;
                    RaisePropertyChanged("IsCase");
                    RaisePropertyChanged("IsCaseSymbol");
                }
            }
        }

        public string IsCaseSymbol { get { return Contact.IsCaseSymbol; } }

        public bool IsActive
        {
            get { return Contact.IsActive; }
            set
            {
                if (Contact.IsActive != value)
                {
                    Contact.IsActive = value;
                    RaisePropertyChanged("IsActive");
                }
            }
        }
        public bool IsWithin21DayWindow
        {
            get
            {
                DateTime today = DateTime.Today;
                if(today >= this.DateOfLastContact.Value.AddDays(1) && today <= (new DateTime(DateOfLastFollowUp.Value.Year, DateOfLastFollowUp.Value.Month, DateOfLastFollowUp.Value.Day, 23, 59, 59))) 
                {
                    return true;
                }
                return false;
            }
        }
        public string ContactID
        {
            get { return Contact.ContactID; }
        }
        public int UniqueKey
        {
            get { return Contact.UniqueKey; }
            set
            {
                if (Contact.UniqueKey != value)
                {
                    Contact.UniqueKey = value;
                    RaisePropertyChanged("UniqueKey");
                    RaisePropertyChanged("ContactID");
                }
            }
        }
        
        #endregion // Properties

        #region Constructors
        /// <summary>
        /// Constructor
        /// </summary>
        public ContactViewModel()
        {
            Contact = new Contact();
        }

        public ContactViewModel(Contact newContact)
        {
            Contact = new Contact();
            UpdateContact(newContact);
        }

        //public ContactViewModel(CaseContactPairViewModel caseContactPair, int uniqueKey)
        //{
        //    Contact = new Contact();
        //    CreateContactFromCase(caseContactPair, uniqueKey);
        //}

        public ContactViewModel(CaseViewModel caseVM, int uniqueKey)
        {
            Contact = new Contact();
            CreateContactFromCase(caseVM, uniqueKey);
        }
        #endregion // Constructors

        #region Methods

        public override string ToString()
        {
            return ContactID + " : " + Surname + ", " + OtherNames + " : " + GenderAbbreviation;
        }

        private void CreateContactFromCase(CaseViewModel caseVM, int uniqueKey)
        {
            this.AgeUnit = caseVM.AgeUnit;
            this.Age = caseVM.Age;
            this.HeadOfHousehold = caseVM.HeadOfHousehold;
            this.District = caseVM.District;
            this.Gender = caseVM.Gender;
            this.IsCase = true;
            this.OtherNames = caseVM.OtherNames;
            this.RecordId = caseVM.RecordId;
            this.UniqueKey = uniqueKey;
            this.SubCounty = caseVM.SubCounty;
            this.Surname = caseVM.Surname;
            this.Village = caseVM.Village;
        }

        public void UpdateContact(Contact updatedContact)
        {
            this.AgeUnit = updatedContact.AgeUnit;
            this.Age = updatedContact.Age;
            this.DateOfLastContact = updatedContact.DateOfLastContact;
            this.FirstSaveTime = updatedContact.FirstSaveTime;
            this.LastSourceCase = updatedContact.LastSourceCase;
            this.District = updatedContact.District;
            this.Gender = updatedContact.Gender;
            this.LC1Chairman = updatedContact.LC1Chairman;
            this.HeadOfHousehold = updatedContact.HeadOfHousehold;
            this.HCW = updatedContact.HCW;
            this.HCWFacility = updatedContact.HCWFacility;
            Contact.IsCase = updatedContact.IsCase;
            this.OtherNames = updatedContact.OtherNames;
            this.RecordId = updatedContact.RecordId;
            this.SubCounty = updatedContact.SubCounty;
            this.Surname = updatedContact.Surname;
            this.UniqueKey = updatedContact.UniqueKey;
            Contact.IsActive = updatedContact.IsActive;
            this.Phone = updatedContact.Phone;
            this.RiskLevel = updatedContact.RiskLevel;
            this.Village = updatedContact.Village;
        }

        public void UpdateContactFormDataOnly(Contact updatedContact)
        {
            this.AgeUnit = updatedContact.AgeUnit;
            this.Age = updatedContact.Age;
            this.District = updatedContact.District;
            this.Gender = updatedContact.Gender;
            this.LC1Chairman = updatedContact.LC1Chairman;
            this.HeadOfHousehold = updatedContact.HeadOfHousehold;
            this.HCW = updatedContact.HCW;
            this.HCWFacility = updatedContact.HCWFacility;
            this.OtherNames = updatedContact.OtherNames;
            this.SubCounty = updatedContact.SubCounty;
            this.Surname = updatedContact.Surname;
            this.Phone = updatedContact.Phone;
            this.RiskLevel = updatedContact.RiskLevel;
            this.Village = updatedContact.Village;
        }
        #endregion // Methods

        #region Commands
        void UpdateExecute(Contact updatedContact)
        {
            UpdateContact(updatedContact);
        }

        public ICommand Update { get { return new RelayCommand<Contact>(UpdateExecute); } }
        #endregion
    }
}
